package com.yyge.controller.user;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yyge.annotation.admin.Admin;
import com.yyge.controller.BaseController;
import com.yyge.controller.user.req.UserAddReq;
import com.yyge.controller.user.req.UserReq;
import com.yyge.controller.user.resp.UserResp;
import com.yyge.convertor.UserConvertor;
import com.yyge.dto.Query;
import com.yyge.dto.ResultCode;
import com.yyge.entity.User;
import com.yyge.service.UserService;
import com.yyge.dto.R;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yyge.util.DateUtil;
import com.yyge.util.HttpUtil;
import com.yyge.util.StringUtil;
import com.yyge.vo.PageVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;

import javax.crypto.spec.PSource;
import java.util.*;

@RestController
@RequestMapping("/user")
@Api(value = "用戶管理相关接口",tags = "用户管理相关接口")
public class UserController extends BaseController<User, UserResp, UserConvertor> {
    // 注入业务逻辑层
    private UserService service;
    @Autowired/*自动装配*/
    public void setService(UserService userService){
        this.service=userService;
    }

    @Admin //只有管理员使用
    @GetMapping/* GET(SELECT): 查询 */
    @ApiOperation(value = "用户分页查询",notes = "用户分页查询")
    public R<?> get(UserReq userReq, Query query) throws Exception  {
        QueryWrapper<User> wrapper = this.getWrapper(UserConvertor.MAPPER.ob2en(userReq));
        Page<User> userPage = this.query2Page(wrapper, query, (q, w) -> service.page(q, w));
        PageVo<UserResp> userRespPageVo = this.page2PageVo(userPage, UserConvertor.MAPPER::ob2respArr);
        return R.ok(userRespPageVo);
    }


    @PostMapping/* POST(CREATE): 新增&登陆 */
    @ApiOperation(value = "新增用戶",notes = "新增用戶")
    public R<?> post(@Validated @RequestBody UserAddReq addReq){
        User user = UserConvertor.MAPPER.ob2en(addReq);
        if(Objects.isNull(user.getExpirationTime())){
            Date format = DateUtil.format("2000-01-01", 1);
            user.setExpirationTime(format); //时间类没有进行转换 所以重新赋值
        }else{
          user.setExpirationTime(addReq.getExpirationTime()); //时间类没有进行转换 所以重新赋值
        }


        //校验是否重复
        User oldUser = service.getOne(new LambdaQueryWrapper<User>().eq(User::getName, addReq.getName()).last("limit 1"));
        if(Objects.nonNull(oldUser)){
            throw new RuntimeException("当前用户名已被使用");
        }

        //赋值一些默认值
        user.setBalance(0F);
        user.setJsUpperLimit(50);
        user.setUrlUpperLimit(20);

        //生成秘钥
        user.setStrKey(StringUtil.getRandomString(20,0));
        user.setIp(HttpUtil.getIp()); //赋值ip
        user.setUserAgent(HttpUtil.getUA()); //赋值UA
        user.setCreateUser(this.getUser().getId()); //创建人
        user.setUpdateUser(this.getUser().getId()); //更新者

        //密码加密
        String hashpw = BCrypt.hashpw(user.getPassword());
        user.setPassword(hashpw);

        //默认头像
        user.setAvatar("https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png");
        boolean i=service.save(user);
        return i?R.ok("新增成功！"):R.error(ResultCode.SYSTEM_SERVICE_ADD_ERROR);
    }

    @PutMapping/* POST(CREATE): 更新 */
    public R out(@RequestBody User user){
        Boolean i=service.updateById(user);
        return i?R.ok("修改成功！"):R.error(ResultCode.SYSTEM_SERVICE_MODIFY_ERROR);
    }

    @PatchMapping/* PUT(UPDATE): 部分更新 */
    public R patch(@RequestBody User user){
        return null;
    }

    @Admin
    @DeleteMapping("/{id}")/* DELETE(DELETE): 删除&&批量删除 */
    @ApiOperation(value = "注销用户",notes = "注销用户")
    public R delete(@PathVariable("id") Long[] list){
        boolean i = service.removeByIds(Arrays.asList(list));
        return i?R.ok("修改成功！"):R.error(ResultCode.SYSTEM_SERVICE_DELETE_ERROR);
    }
}


